#include <iostream>
#include <vector>
#include <queue>
#include <pthread.h>
#include <unistd.h>

class ThreadPool 
{
public:
    typedef struct 
    {
        void* (*func)(void*);
        void* arg;
    } task_t ;

    ThreadPool(int threadsNum)
        : isStop(false)
    {
        pthread_mutex_init(&mutex, NULL);
        pthread_cond_init(&cond, NULL);

        for (int i = 0; i < threadsNum; i++) {
            pthread_t tid;
            pthread_create(&tid, NULL, threadFunc, this);
            threads.push_back(tid);
        }
    }

    static void* threadFunc(void* arg) 
    {
        ThreadPool* pool = static_cast<ThreadPool*>(arg);

        while (1) {
            // 1. 申请锁
            pthread_mutex_lock(&pool->mutex);

            // 2. 检查线程池是否关闭
            if (pool->isStop) {
                pthread_mutex_unlock(&pool->mutex);
                break;
            }

            // 3. 检查队列中是否有任务
            while (pool->tasks.empty()) {
                pthread_cond_wait(&pool->cond, &pool->mutex);
            }

            // 4. 获取任务
            task_t task = pool->tasks.front();
            pool->tasks.pop();

            // 5. 释放锁
            pthread_mutex_unlock(&pool->mutex);

            // 6. 执行
            task.func(task.arg);
        }   

        return NULL;
    }

    bool addTask(void* (*func)(void*), void* arg) 
    {
        pthread_mutex_lock(&mutex);

        // 线程池关闭
        if (isStop) {
            pthread_mutex_unlock(&mutex);
            return false;
        }

        task_t task;
        task.func = func;
        task.arg = arg;

        tasks.push(task);

        // 唤醒任务线程
        pthread_cond_signal(&cond);
        pthread_mutex_unlock(&mutex);
        return true;
    }

    void stop() 
    {
        pthread_mutex_lock(&mutex);
        isStop = true;

        pthread_cond_broadcast(&cond);
        pthread_mutex_unlock(&mutex);

        for (auto tid : threads) {
            pthread_join(tid, NULL);
        }
    }

    ~ThreadPool() 
    {
        stop();
        pthread_mutex_destroy(&mutex);
        pthread_cond_destroy(&cond);
    }

private:
    pthread_mutex_t mutex;
    pthread_cond_t cond;
    std::queue<task_t> tasks;
    std::vector<pthread_t> threads;
    bool isStop;
};

void* print(void* arg) 
{
    int* num = static_cast<int*>(arg);
    std::cout << *num << std::endl;
    return NULL;
}

int main()
{
    ThreadPool* pool = new ThreadPool(3);

    int x1 = 3;
    int x2 = 4;
    int x3 = 2;
    int x4 = 1;

    pool->addTask(print, &x1);
    pool->addTask(print, &x2);
    pool->addTask(print, &x3);
    pool->addTask(print, &x4);

    sleep(5);
    
    return 0;
}


// #include <iostream>
// #include <pthread.h>
// #include <queue>
// #include <vector>


// class ThreadPool 
// {
// public:
//     typedef void*(task_func)(void*);

//     typedef struct
//     {
//         void* (*func) (void*);
//         void* arg;
//     } task_t;

//     ThreadPool(int threadNums) : isStop(false)
//     {
//         pthread_mutex_init(&mutex, NULL);
//         pthread_cond_init(&cond, NULL);

//         for (int i = 0; i < threadNums; i++) {
//             pthread_t tid;
//             pthread_create(&tid, NULL, threadFunc, this);
//             threads.push_back(tid);
//         }
//     }

//     void stop() 
//     {
//         pthread_mutex_lock(&mutex);
//         isStop = true;

//         pthread_cond_broadcast(&cond); // 唤醒所有线程
//         pthread_mutex_unlock(&mutex);

//         for (int i = 0; i < threads.size(); i++) {
//             pthread_join(threads[i], NULL); // 等待所有线程结束
//         }
//     }

//     ~ThreadPool() 
//     {
//         stop();
//         pthread_mutex_destroy(&mutex);
//         pthread_cond_destroy(&cond);
//     }

//     static void* threadFunc(void* arg) 
//     {
//         ThreadPool* pool = static_cast<ThreadPool*>(arg);
//         while (true) {
//             // 1. 申请锁
//             pthread_mutex_lock(&pool->mutex);

//             // 2. 检查线程池是否关闭
//             if (pool->isStop) {
//                 pthread_mutex_unlock(&pool->mutex);
//                 break;
//             }

//             // 3. 检查线程池中是否有任务
//             while (pool->q.empty()) {
//                 pthread_cond_wait(&pool->cond, &pool->mutex);
//             }

//             // 4. 从队列中获取任务
//             task_t task = pool->q.front();
//             pool->q.pop();

//             // 5. 释放锁
//             pthread_mutex_unlock(&pool->mutex);

//             // 6. 执行任务
//             task.func(task.arg);
//         }
//         return NULL;
//     }

//     bool addTask(void*(*func)(void*) , void* arg) 
//     {
//         pthread_mutex_lock(&mutex);

//         if (isStop) {
//             pthread_mutex_unlock(&mutex);
//             return false;
//         }

//         task_t task;
//         task.func = func;
//         task.arg = arg;

//         q.push(task);

//         pthread_cond_signal(&cond);
//         pthread_mutex_unlock(&mutex);
//         return true;
//     }

// private:
    

//     pthread_mutex_t mutex;
//     pthread_cond_t cond;
//     std::queue<task_t> q;
//     std::vector<pthread_t> threads;
//     bool isStop;
// };

// void* print(void* arg) 
// {
//     int* num = static_cast<int*>(arg);

//     std::cout << *num << std::endl;

//     return NULL;
// }

// int main()
// {
//     ThreadPool* pool = new ThreadPool(3);

//     int x = 10;
//     pool->addTask(print, &x);
//     pool->addTask(print, &x);
//     pool->addTask(print, &x);
//     pool->addTask(print, &x);
//     pool->addTask(print, &x);
//     pool->addTask(print, &x);

//     while (1) {

//     }
//     return 0;
// }